package com.briup.pts.util;

import com.briup.pts.config.exception.ServiceException;
import com.briup.pts.config.response.ResultCode;
import io.jsonwebtoken.*;

import java.util.Date;
import java.util.Map;

/**
 * jwt工具类，用于简化token的签发和校验过程
 */
public class JwtUtil {
    // 有效时长 1天后过期
    private final static long EXPIRATION = 24 * 60 * 60 * 1000;
    // 设置密钥
    private final static String SECRET_KEY = "briup_secret";
    // 设置签发的算法
    private final static SignatureAlgorithm ALGORITHM = SignatureAlgorithm.HS512;

    /**
     * 根据传入的数据签发token
     *
     * @return token字符串
     */
    public static String sign(Map<String, Object> claims) {
        return Jwts.builder()
                // 设置claims载荷
                .addClaims(claims)
                // 设置过期时间
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION))
                // 指定签发的密钥和算法
                .signWith(ALGORITHM, SECRET_KEY)
                .compact();
    }


    /**
     * 根据属性名和属性类型从token中获取属性值
     *
     * @param token     token字符串
     * @param fieldName 属性名
     * @param fieldType 属性类型
     * @return 属性值
     */
    public static <T> T fieldValue(String token, String fieldName, Class<T> fieldType) {
        Claims claims = parse(token);
        return claims.get(fieldName, fieldType);
    }

    private static Claims parse(String token) {
        if (token == null || token.trim().isEmpty()) {
            throw new ServiceException(ResultCode.TOKEN_IS_MISS);
        }

        try {
            // 解析token，获取其内部的载荷数据
            return Jwts.parser()
                    .setSigningKey(SECRET_KEY)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (ExpiredJwtException e) {
            // 说明当前的token已失效，告知用户需要重新登录
            throw new ServiceException(ResultCode.TOKEN_IS_TIMEOUT);
        } catch (MalformedJwtException | SignatureException e) {
            // 说明token令牌被篡改，或密钥对不上
            throw new ServiceException(ResultCode.TOKEN_IS_INVALID);
        }
    }


}
